<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 对象拦截
    // Object.defineProperty()

    // Vue2 的底层 响应式 原理Object.defineProperty()

    // 这个会直接在一个对象上定义一个新属性，或者修改一个对象的现有属性，并返回此对象。
    // 参数  obj, prop, descriptor
    //  obj   要定义属性的对象。
    //  prop  要定义或修改的属性的名称或 Symbol 。
    //  descriptor  要定义或修改的属性描述符。
    // 返回值:  被传递给函数的对象

    // 一、创建一个可控对象
    // var obj = { 键名：键值 }
    // var val = "张三";
    // var obj = Object.defineProperty({}, "name", {
    //   get: function () {
    //     console.log("get...")
    //     return val; // 为了解决get会无限触发的问题
    //   },
    //   set: function (newvalue) {
    //     console.log("修改了", newvalue);
    //     if (val !== newvalue)
    //       val = newvalue;
    //   },
    //   configurable: true,
    //   enumerable: true
    // })
    // // console.log(obj);
    // obj.name;           // 获取name属性  调用get
    // obj.name = "李四";  // 修改name属性 调用set



    // 二、修改一个对象为可控制对象
    // var obj = {
    //   name: "张三",
    //   age: 20
    // }
    // // 修改 obj里的 age属性为 可控制属性
    // var obj2 = Object.defineProperty(obj,"age",{
    //     get:function(){
    //         console.log('get...');
    //         return 20;
    //     },
    //     set:function(newvalue){
    //         console.log("set",newvalue)
    //     },
    //     configurable:true,
    //     enumerable:true
    // })
    // obj2.age // get函数调用
    // obj2.age = 100 // set函数被调用
    // Object.defineProperty(obj,"name",{
    //     get:function(){
    //         return "张三";
    //     },
    //     set:function(newvalue){
    //         console.log("set",newvalue)
    //     },
    //     configurable:true,
    //     enumerable:true
    // })
    // console.log(obj);



  
    var obj = {
      name: "张三",
      age: 20
    }
    // 封装一个 观察数据的函数
    function observe(obj){
      for(var key in obj){
        // 解决get会无限触发 的bug
        var val = obj[key]
        Object.defineProperty(obj,key,{
          get:function(){
            console.log('get');
            return val 
            // 这里需要返回自己的属性值  但是obj已经被数据劫持 再访问obj[key] 会无限调用get方法 所以用变量表示返回值
            // 返回值是变量 避免返回值是obj[key] 会无限递归

          },
          set:function(newvalue){
            if(obj[key] != newvalue ){
              obj[key] = newvalue
            }
          },
          configurable:true,
          enumerable:true
        })
      }
    }
    observe(obj)
    console.log(obj);
    



  </script>
</body>

</html>